<template>
  <div class="ie-form">

    <n-form
      v-bind="$FormProps"
      :model="formValue"
      :rules="formProps.formRules"
      size="medium"
      ref="formRef"
    >

      <!-- disable chrome autocomplete -->
      <input name="password" type="password" style="display:none" autocomplete="new-password" />

      <n-form-item
        v-for="key in Object.keys(formProps.formInputs)"
        :label="formProps.formInputs[key].title"
        :path="key"
        :key="key"
      >

        <!-- TEXTAREA -->
        <n-input
          v-if="formProps.formInputs[key].type === 'textarea'"
          v-model:value.trim="formValue[key]"
          type="textarea"
          :autosize="{
            minRows: 3,
            maxRows: formProps.formInputs[key].maxRows || 5
          }"
          :maxlength="formProps.formInputs[key].maxlength || 300"
          show-count
          clearable
        />

        <!-- SELECT -->
        <n-select
          v-else-if="formProps.formInputs[key].type === 'select'"
          v-model:value="formValue[key]"
          :options="formProps.formInputs[key].options || []"
          clearable
        />

        <!-- DATE -->
        <n-date-picker
          v-else-if="formProps.formInputs[key].type === 'date'"
          v-model:value="formValue[key]"
          v-bind="formProps.formInputs[key]"
          type="datetime"
          clearable
        />

        <!-- AYSNC SELECT -->
        <ie-async-select
          v-else-if="formProps.formInputs[key].type === 'async'"
          v-model:value="formValue[key]"
          v-bind="formProps.formInputs[key]"
        />

        <!-- UPLOAD -->
        <ie-upload
          v-else-if="formProps.formInputs[key].type === 'upload'"
          v-model:value="formValue[key]"
          v-bind="formValue"
        />

        <!-- SWITCH -->
        <n-switch
          v-else-if="formProps.formInputs[key].type === 'switch'"
          v-model:value="formValue[key]"
        />

        <!-- MARKDOWN -->
        <ie-markdown
          v-else-if="formProps.formInputs[key].type === 'markdown'"
          v-model:value="formValue[key]"
        />

        <!-- RICHTEXT -->
        <ie-editor
          v-else-if="formProps.formInputs[key].type === 'richtext'"
          v-model:value="formValue[key]"
        />

        <!-- TAG -->
        <n-space v-else-if="formProps.formInputs[key].type === 'tag'">
          <n-tag v-for="item in formValue[key]" :key="item">{{ item }}</n-tag>
        </n-space>

        <!-- PASSWORD -->
        <n-input
          v-else-if="formProps.formInputs[key].type === 'password'"
          v-model:value.trim="formValue[key]"
          type="password"
          clearable
        />

        <!-- INPUT -->
        <n-input
          v-else
          v-model:value.trim="formValue[key]"
          clearable
        />

        <template v-if="formProps.formInputs[key].tooltip" #label>
          <n-tooltip trigger="hover">
            <template #trigger>
              <n-icon size="18" style="vertical-align: text-bottom;">
                <question-circle24-regular />
              </n-icon>
            </template>
            {{ formProps.formInputs[key].tooltip }}
          </n-tooltip>
          {{ formProps.formInputs[key].title }}
        </template>

      </n-form-item>

    </n-form>
  </div>
</template>

<script>
import { modelValidator } from '/@/model'

export const formPropsDefine = {
  model: {
    validator: modelValidator
  },
  passby: {
    type: Array,
    default: () => []
  },
  formInputs: {
    type: Object,
    default: () => ({})
  },
  formRules: {
    type: Object,
    default: () => ({})
  },
  // formProps
  labelWidth: {
    type: Number,
    default: 120
  },
  labelPlacement: {
    type: String,
    validator: v => ['left', 'top'].includes(v),
    default: 'top'
  },
  disabled: {
    type: Boolean,
    default: false
  }
}
</script>
<script setup>
import { ref } from 'vue'
import { cloneDeep } from 'lodash-es'

import { cleanObject, getTimestamptz } from '/@/utils/helper'
import normalizeFormInputs from '/@/utils/normalize-form-inputs'

import QuestionCircle24Regular from '@vicons/fluent/QuestionCircle24Regular'

const props = defineProps(formPropsDefine)

const {
  model,
  passby,
  formInputs,
  formRules,
  ...$FormProps
} = props

let formProps

if (model) {
  formProps = normalizeFormInputs(model, passby)
} else {
  formProps = { formInputs, formRules, initValues: {} }

  for (let key in formInputs) {
    formProps.initValues[key] = formInputs[key]?.initValue || null
  }
}

const formRef = ref()
const formValue = ref(
  cloneDeep(formProps.initValues)
)

function set(values) {
  for (let key in formProps.initValues) {
    const type = formProps.formInputs[key]?.type

    if (type === 'date') {
      formProps.initValues[key] = getTimestamptz(values[key])
    } else {
      formProps.initValues[key] = values[key] || formProps.initValues[key]
    }
  }
  formValue.value = cloneDeep(formProps.initValues)
}

function submit() {
  return new Promise((resolve, reject) => {
    return formRef.value.validate(err => {
      if (!err) {
        return resolve(
          cleanObject(formValue.value)
        )
      }
    })
  })
}

function reset() {
  formValue.value = cloneDeep(formProps.initValues)
}

defineExpose({
  set,
  submit,
  reset
})
</script>

<style lang="less">
.ie-form {
  background-color: #fff;
  padding: 32px 24px;

  .n-form {
    margin: 0 auto;
    max-width: 800px;
  }

  .ie-markdown {
    border: 1px solid rgb(224, 224, 230);
    border-radius: 3px;
  }
}
</style>
